/*
 * tlistaporo.h
 *
 *  Created on: 09/12/2009
 *      Author: javier
 */

#ifndef TLISTAPORO_H_
#define TLISTAPORO_H_

#include <iostream>
#include "tporo.h"

using namespace std;
/** \file tlistaporo.h
 *  \brief Implementaciones de las clases TListaNodo, TListaPosicion y TListaPoro.
 *
 * Este fichero contiene las definiciones de las clases mencionadas anteriormente; donde las dos primeras son auxiliares de la tercera.
 */

class TListaPoro;

/** \brief Estructura de TListaNodo.
 *
 *  Esta clase se encarga de definir el tipo de nodo que ocupara lugar en la lista que queremos forma en TListaPoro.
 */
class TListaNodo
{
        friend class TListaPoro;
        friend class TListaPosicion;


        friend ostream & operator<<(ostream &, const TListaPoro &);

        public:

                /** \brief Constructor de la clase.
                 *
                 * Constructor de la clase por defecto, donde creamos un nodo por defecto.
                 */
                TListaNodo();

                /** \brief Constructor de copia.
                 *
                 * Constructor de copia de la clase TListaNodo.
                 * \param n Un TListaNodo desde el que se copia.
                 */
                TListaNodo( const TListaNodo &);

                /** \brief Destructor.
                 *
                 * Destructor de la clase.
                 */
                ~TListaNodo();

                /** \brief Sobrecarga del operador asignación.
                 *
                 * En esta sobrecarga asignamos el contenido del argumento al TListaNodo que llame al método.
                 * \param n TListaNodo del cual asignamos.
                 * \return TListaNodo& es devuelto.
                 */
                TListaNodo & operator=( const TListaNodo &);



        private:

                /** \brief TPoro e.
                 *
                 * TPoro que forma parte del nodo.
                 */
                TPoro e;

                /** \brief puntero a TListaNodo.
                 *
                 * Este puntero nos señalará el TListaNodo en una posicion anterior a este.
                 */
                TListaNodo *anterior;

                /** \brief puntero a TListaNodo.
                 *
                 * Este puntero nos señalará el TListaNodo en la siguiente posicion.
                 */
                TListaNodo *siguiente;
};


/** \brief Estructura de TListaPosicion
 *
 *      Esta clase se encarga de definir un puntero TListaNodo, con el cual operaremos.
 */
class TListaPosicion
{
        friend class TListaPoro;
        friend ostream & operator<<(ostream &, const TListaPoro &);

        public:

                /** \brief Constructor por defecto.
                 *
                 * Constructor de la clase, pone el puntero a NULL.
                 */
                TListaPosicion();

                /** \brief Constructor de copia.
                 *
                 * Constructor de copia.
                 * \param p TListaPosicion del que copiamos.
                 */
                TListaPosicion( const TListaPosicion &);

                /** \brief Destructor.
                 *
                 * Si el puntero pos es distinto de NULL, hacemos un delete, y lo apuntamos a NULL.
                 */
                ~TListaPosicion();

                /** \brief Sobrecarga del operador asignación.
                 *
                 * Asignamos el contenido de del parámetro al objeto que llama al método.
                 * \param p TListaPosicion del cual asignamos.
                 * \return Devuelve un TListaPosicion&.
                 */
                TListaPosicion& operator=( const TListaPosicion &);

                /** \brief Sobrecarga del operador igualdad.
                 *
                 * Comparamos los punteros pos para comprobar si apuntan al mismo sitio.
                 * \param p
                 * \return Devuelve un bool.
                 */
                bool operator==( const TListaPosicion &);

                /** \brief Metodo Anterior().
                 *
                 * Anterior devuelve un TListaPosicion con el contenido del nodo anterior.
                 * \return  Devuelve un TListaPosicion.
                 */
                TListaPosicion Anterior() const;

                /** \brief Metodo Siguiente().
                 *
                 * Siguiente devuelve un TListaPosicion con el contenido del nodo siguiente.
                 * \return  Devuelve un TListaPosicion.
                 */
                TListaPosicion Siguiente() const;

                /** \brief Metodo EsVacia().
                 *
                 * Devuelve true si es vacia y false si no lo es.
                 * \return  Devuelve un bool.
                 */
                bool EsVacia() const;

        private:

                /** \brief puntero a TListaNodo
                 *
                 * Puntero a un objeto TListaNodo.
                 */
                TListaNodo *pos;

};

/** \brief Estructura de TListaPoro.
 *
 * Esta clase se encarga de definir una lista teniendo en su parte privada un puntero al primero de la lista y otro al ultimo
 */
class TListaPoro
{

	/** \brief Sobrecarga del operador "<<", función amiga de TListaPoro.
	 *
	 * Función amiga que se encarga de mostrar por pantalla, en un formato determinado un TListaPoro que le pasemos.
	 * Es tambien amiga de TListaPosicion y TListaNodo, para que pueda acceder a todas las componentes a la hora de mostrar;
	 *
	 * \param os Ostream donde guardaremos la informacion que queremos mostrar.
	 * \param l Lista que queremos mostrar.
	 *
	 * \return La funcion devuelve un ostream&.
	 */
       friend ostream & operator<<(ostream &, const TListaPoro &);

        public:
                /** \brief Constructor de TListaPoro.
                 *
                 * Constructor de TListaPoro.
                 */
                TListaPoro();
                /** \brief Constructor de copia.
                 *
                 * Constructor de copia.
                 * \param p TListaPoro del que copiamos.
                 */
                TListaPoro( const TListaPoro & );
                /** \brief Destructor.
                 *
                 * Destruimos una TListaPoro.
                 */
                ~TListaPoro();
                /** \brief Sobrecarga del operador asignación.
                 *
                 * Asignamos el contenido del parámetro al objeto que llama al método.
                 * \param p TListaPoro del cual asignamos.
                 * \return Devuelve un TListaPoro&.
                 */
                TListaPoro& operator=( const TListaPoro &);
                /** \brief Sobrecarga del operador igualdad.
                 *
                 * Devolvemos true si las dos TListaPoro son iguales.
                 * \param p TListaPoro del la cual vemos si es igual.
                 * \return Devuelve un bool.
                 */
                bool operator ==( const TListaPoro & ) const;
                /** \brief Sobrecarga del operador suma.
                 *
                 * Devolvemos la suma de dos TListaPoro.
                 * \param l TListaPoro del la cual sumamos.
                 * \return Devuelve un TListaPoro.
                 */
                TListaPoro operator+( const TListaPoro &); // Quizas se puede poner a const.
                /** \brief Sobrecarga del operador resta.
                 *
                 * Devolvemos la resta de dos TListaPoro.
                 * \param l TListaPoro del la cual restamos.
                 * \return Devuelve un TListaPoro.
                 */
                TListaPoro operator-( const TListaPoro &);
                /** \brief Metodo EsVacia.
                 *
                 * Devolvemos true si la TListaPoro esta vacia.
                 * \return Devuelve un bool.
                 */
                bool EsVacia() const;
                /** \brief Metodo Insertar.
                 *
                 * Devolvemos true si se ha podido insertar un TPoro en la lista.
                 * \param p TPoro a insertar.
                 * \return Devuelve un bool.
                 */
                bool Insertar( const TPoro &);
                /** \brief Metodo Borrar.
                 *
                 * Devolvemos true si se ha podido Borrar un TPoro en la lista.
                 * \param p TPoro a borrar.
                 * \return Devuelve un bool.
                 */
                bool Borrar( const TPoro &);
                /** \brief Metodo Borrar.
                 *
                 * Devolvemos true si se ha podido Borrar la posicion en la lista.
                 * \param p TListaPosicion a borrar.
                 * \return Devuelve un bool.
                 */
                bool Borrar( const TListaPosicion &);
                /** \brief Metodo Obtener.
                 *
                 * Devolvemos el TPoro de la posicion de la lista.
                 * \param p TListaPosicion a obtener.
                 * \return Devuelve un TPoro.
                 */
                TPoro Obtener( const TListaPosicion &);
                /** \brief Metodo Buscar.
                 *
                 * Devolvemos true si se ha encontrado el TPoro en la lista.
                 * \param p TPoro a buscar.
                 * \return Devuelve un bool.
                 */
                bool Buscar( const TPoro &) const;
                /** \brief Metodo Longitud.
                 *
                 * Devolvemos la longitud de la lista
                 * \return Devuelve un int.
                 */                
                int Longitud();
                /** \brief Metodo Primera.
                 *
                 * Devolvemos la primera TListaPosicion de la lista
                 * \return Devuelve un TListaPosicion.
                 */            
                TListaPosicion Primera();
                /** \brief Metodo Ultima.
                 *
                 * Devolvemos la ultima TListaPosicion de la lista
                 * \return Devuelve un TListaPosicion.
                 */            
                TListaPosicion Ultima();

        private:
                /** \brief puntero a TListaNodo
                 *
                 * Puntero a un objeto TListaNodo.
                 */
                TListaNodo *primero;
                /** \brief puntero a TListaNodo
                 *
                 * Puntero a un objeto TListaNodo.
                 */
                TListaNodo *ultimo;
};



#endif /* TLISTAPORO_H_ */
